package com.skyyan.netty.jjf.test;

import com.skyyan.netty.jjf.codec.JjfMessageDecoder;
import com.skyyan.netty.jjf.codec.JjfMessageEncoder;
import com.skyyan.netty.jjf.protocol.FrameConstants;
import com.skyyan.netty.jjf.protocol.Message;
import com.skyyan.netty.jjf.protocol.WaterElectricityPriceQueryMessage;
import com.skyyan.netty.jjf.util.IntThreeBytesUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.embedded.EmbeddedChannel;

import java.util.Arrays;

/**
 * WaterElectricityPriceQueryMessage测试类的main方法实现
 * 用于独立运行测试，验证上行和下行报文的编解码功能
 */
public class WaterElectricityPriceQueryMessageTestMain {

    public static void main(String[] args) {
        System.out.println("开始测试WaterElectricityPriceQueryMessage...");
        System.out.println("==========================================");

        try {
            testUplinkMessage();
            System.out.println();
//            testDownlinkMessage();
//            System.out.println();
//            testPriceValueConversion();

            System.out.println("==========================================");
            System.out.println("所有测试通过!");
        } catch (Exception e) {
            System.err.println("测试失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private static void testUplinkMessage() {
        System.out.println("测试上行报文编解码...");

        // 准备测试数据
        byte[] deviceRegId = new byte[16];
        for (int i = 0; i < 16; i++) {
            deviceRegId[i] = (byte) (i + 1);
        }

        int deviceSerialNoInt = 7891;
        byte[] deviceSerialNo= IntThreeBytesUtil.intTo3BytesLittleEndian(deviceSerialNoInt);
        // 创建上行报文
        WaterElectricityPriceQueryMessage.Uplink uplinkMsg =
            new WaterElectricityPriceQueryMessage.Uplink(deviceRegId, deviceSerialNoInt);

        System.out.println("原始上行报文: " + uplinkMsg);

        // 创建EmbeddedChannel用于测试编解码
        EmbeddedChannel channel = new EmbeddedChannel();
        channel.pipeline()
            .addLast(new JjfMessageEncoder())
            .addLast(new JjfMessageDecoder());

        // 编码
        boolean writeResult = channel.writeOutbound(uplinkMsg);
        System.out.println("编码结果: " + (writeResult ? "成功" : "失败"));

        ByteBuf encoded = channel.readOutbound();
        if (encoded == null) {
            System.err.println("编码后的ByteBuf为null");
            return;
        }

        System.out.println("编码后的数据长度: " + encoded.readableBytes());
        System.out.print("编码后的数据(HEX): ");
        for (int i = 0; i < encoded.readableBytes(); i++) {
            System.out.printf("%02X ", encoded.getByte(encoded.readerIndex() + i));
        }
        System.out.println();

        // 解码
        boolean readResult = channel.writeInbound(encoded);
        System.out.println("写入解码器结果: " + (readResult ? "成功" : "失败"));

        Message decodedMsg = channel.readInbound();
        if (decodedMsg == null) {
            System.err.println("解码后的消息为null");
            return;
        }

        System.out.println("解码后的报文: " + decodedMsg);

        // 验证解码后的消息类型
        if (!(decodedMsg instanceof WaterElectricityPriceQueryMessage.Uplink)) {
            System.err.println("解码后的消息类型不正确");
            return;
        }

        WaterElectricityPriceQueryMessage.Uplink decodedUplink =
            (WaterElectricityPriceQueryMessage.Uplink) decodedMsg;

        // 验证关键字段
        if (!Arrays.equals(deviceRegId, decodedUplink.getDeviceRegIdBytes())) {
            System.err.println("设备注册号不匹配");
            return;
        }

        if (!Arrays.equals(deviceSerialNo, decodedUplink.getDeviceSerialNoBytes())) {
            System.err.println("设备序列号不匹配");
            return;
        }

        if (FrameConstants.CONTROL_UPLINK != decodedUplink.getControl()) {
            System.err.println("控制域不匹配");
            return;
        }

        if (FrameConstants.AFN_WATER_ELECTRICITY_PRICE_QUERY != decodedUplink.getAfn()) {
            System.err.println("AFN不匹配");
            return;
        }

        System.out.println("上行报文编解码测试通过 ✓");
    }

    private static void testDownlinkMessage() {
        System.out.println("测试下行报文编解码...");



        // 价格数据
        byte[] waterPrice1 = new byte[]{0x00, 0x01, 0x10}; // 1.10元
        byte[] waterPrice2 = new byte[]{0x00, 0x02, 0x20}; // 2.20元
        byte[] waterPrice3 = new byte[]{0x00, 0x03, 0x30}; // 3.30元
        byte[] tieredPrice1 = new byte[]{0x00, 0x04, 0x40}; // 4.40元
        byte[] tieredPrice2 = new byte[]{0x00, 0x05, 0x50}; // 5.50元
        byte[] tieredPrice3 = new byte[]{0x00, 0x06, 0x60}; // 6.60元

        // 创建下行报文
        WaterElectricityPriceQueryMessage.Downlink downlinkMsg =
            new WaterElectricityPriceQueryMessage.Downlink(
                (byte) 0x00, // 状态码
                waterPrice1, waterPrice2, waterPrice3,
                tieredPrice1, tieredPrice2, tieredPrice3);

        System.out.println("原始下行报文: " + downlinkMsg);

        // 创建EmbeddedChannel用于测试编解码
        EmbeddedChannel channel = new EmbeddedChannel();
        channel.pipeline()
            .addLast(new JjfMessageEncoder())
            .addLast(new JjfMessageDecoder());

        // 编码
        boolean writeResult = channel.writeOutbound(downlinkMsg);
        System.out.println("编码结果: " + (writeResult ? "成功" : "失败"));

        ByteBuf encoded = channel.readOutbound();
        if (encoded == null) {
            System.err.println("编码后的ByteBuf为null");
            return;
        }

        System.out.println("编码后的数据长度: " + encoded.readableBytes());
        System.out.print("编码后的数据(HEX): ");
        for (int i = 0; i < encoded.readableBytes(); i++) {
            System.out.printf("%02X ", encoded.getByte(encoded.readerIndex() + i));
        }
        System.out.println();

        // 解码
        boolean readResult = channel.writeInbound(encoded);
        System.out.println("写入解码器结果: " + (readResult ? "成功" : "失败"));

        Message decodedMsg = channel.readInbound();
        if (decodedMsg == null) {
            System.err.println("解码后的消息为null");
            return;
        }

        System.out.println("解码后的报文: " + decodedMsg);

        // 验证解码后的消息类型
        if (!(decodedMsg instanceof WaterElectricityPriceQueryMessage.Downlink)) {
            System.err.println("解码后的消息类型不正确");
            return;
        }

        WaterElectricityPriceQueryMessage.Downlink decodedDownlink =
            (WaterElectricityPriceQueryMessage.Downlink) decodedMsg;

        // 验证关键字段

        if ((byte) 0x00 != decodedDownlink.getStatusCodeBCD()) {
            System.err.println("状态码不匹配");
            return;
        }

        if (!Arrays.equals(waterPrice1, decodedDownlink.getWaterPrice1())) {
            System.err.println("1阶水价不匹配");
            return;
        }

        if (!Arrays.equals(waterPrice2, decodedDownlink.getWaterPrice2())) {
            System.err.println("2阶水价不匹配");
            return;
        }

        if (!Arrays.equals(waterPrice3, decodedDownlink.getWaterPrice3())) {
            System.err.println("3阶水价不匹配");
            return;
        }

        if (!Arrays.equals(tieredPrice1, decodedDownlink.getTieredPrice1())) {
            System.err.println("1阶电价不匹配");
            return;
        }

        if (!Arrays.equals(tieredPrice2, decodedDownlink.getTieredPrice2())) {
            System.err.println("2阶电价不匹配");
            return;
        }

        if (!Arrays.equals(tieredPrice3, decodedDownlink.getTieredPrice3())) {
            System.err.println("3阶电价不匹配");
            return;
        }

        if (FrameConstants.CONTROL_DOWNLINK != decodedDownlink.getControl()) {
            System.err.println("控制域不匹配");
            return;
        }

        if (FrameConstants.AFN_WATER_ELECTRICITY_PRICE_QUERY != decodedDownlink.getAfn()) {
            System.err.println("AFN不匹配");
            return;
        }

        System.out.println("下行报文编解码测试通过 ✓");
    }

    private static void testPriceValueConversion() {
        System.out.println("测试价格值转换...");

        WaterElectricityPriceQueryMessage.Downlink downlinkMsg =
            new WaterElectricityPriceQueryMessage.Downlink(
                (byte) 0x00,
                new byte[3], new byte[3], new byte[3],
                new byte[3], new byte[3], new byte[3]);

        // 测试价格值转换
        byte[] priceBytes = new byte[]{0x00, 0x01, 0x10}; // 0x000110 = 272
        int priceValue = downlinkMsg.getPriceValue(priceBytes);
        if (priceValue != 272) {
            System.err.println("价格值转换不正确，期望: 272, 实际: " + priceValue);
            return;
        }

        // 测试获取各级价格值
        byte[] waterPrice1 = new byte[]{0x00, 0x01, 0x10};
        byte[] waterPrice2 = new byte[]{0x00, 0x02, 0x20};
        byte[] waterPrice3 = new byte[]{0x00, 0x03, 0x30};
        byte[] tieredPrice1 = new byte[]{0x00, 0x04, 0x40};
        byte[] tieredPrice2 = new byte[]{0x00, 0x05, 0x50};
        byte[] tieredPrice3 = new byte[]{0x00, 0x06, 0x60};

        WaterElectricityPriceQueryMessage.Downlink priceMsg =
            new WaterElectricityPriceQueryMessage.Downlink(
                (byte) 0x00,
                waterPrice1, waterPrice2, waterPrice3,
                tieredPrice1, tieredPrice2, tieredPrice3);

        if (priceMsg.getWaterPrice1Value() != 272) {
            System.err.println("1阶水价转换不正确");
            return;
        }

        if (priceMsg.getWaterPrice2Value() != 544) {
            System.err.println("2阶水价转换不正确");
            return;
        }

        if (priceMsg.getWaterPrice3Value() != 816) {
            System.err.println("3阶水价转换不正确");
            return;
        }

        if (priceMsg.getTieredPrice1Value() != 1092) {
            System.err.println("1阶电价转换不正确");
            return;
        }

        if (priceMsg.getTieredPrice2Value() != 1364) {
            System.err.println("2阶电价转换不正确");
            return;
        }

        if (priceMsg.getTieredPrice3Value() != 1636) {
            System.err.println("3阶电价转换不正确");
            return;
        }

        System.out.println("价格值转换测试通过 ✓");
    }
}
